Skip to content

refactor: Refactor MockTexeraDB into a JVM singleton#6238

Open
Neilk1021 wants to merge 13 commits into
apache:mainfrom
Neilk1021:task/singleton-mock-texera-db
Open

refactor: Refactor MockTexeraDB into a JVM singleton#6238
Neilk1021 wants to merge 13 commits into
apache:mainfrom
Neilk1021:task/singleton-mock-texera-db

Conversation

@Neilk1021

Copy link
Copy Markdown
Contributor

What changes were proposed in this PR?

Closes #6063 by completely refactoring the MockTexeraDB infrastructure to transition from a distributed process architecture to a centralized, shared-singleton architecture.

  1. High-Performance Shared Singleton Architecture: Refactored the core setup by splitting the original MockTexeraDB trait into a companion object MockTexeraDB singleton and a lightweight trait MockTexeraDB interface wrapper. The background EmbeddedPostgres database engine process is now booted exactly once per JVM lifecycle via synchronized initialization. Individual test suites dynamically provision an isolated schema sandbox via cheap CREATE DATABASE queries instead of spawning heavy process-level instances.
  2. DDL Caching and Regex Optimization: Removed massive runtime file I/O and processing bottlenecks. The full-text search index string regex modifications and SQL script cleaning are handled once and cached globally in memory (ddlScript), preventing parallel test suites from thrashing disk resources over the same sql/texera_ddl.sql file.
  3. Robust Connection Lifecycle Management: Addressed multi-threaded race conditions crashing asynchronous multipart uploads (PSQLException: Cannot commit when autoCommit is enabled). Refactored SqlServer.withTransaction to safely intercept test configurations, bypassing rigid jOOQ transaction managers to manually cycle and restore autoCommit states cleanly on the active connection handle without leaking parameters across tests.

Performance Impact

Moving database instantiation, parsing, and regex evaluation out of the distributed trait lifecycle and into a centralized static memory layer resulted in a dramatic reduction in test suite runtime.

  • Main Branch Baseline / Prior Implementation: 5 minutes 40 seconds
  • This PR: 4 minutes 5 seconds (Total execution time reduced by ~28% locally).

Any related issues, documentation, discussions?

Follow up on #4525 where a refactor of MockTexeraDB was needed to allow for future concurrent execution of test suites. Structural baseline was cherry-picked and heavily adapted from #4527, specifically commit bd93161 written by @Yicong-Huang.

How was this PR tested?

Verified by running full, clean compilations and local stress tests on JDK 17 to validate that the structural split preserves total API backward compatibility across the codebase.

Additionally validated that high-concurrency race conditions (such as the asynchronous multi-threaded tests inside DatasetResourceSpec) converge gracefully without experiencing deadlocks, thread crashes, or connection state leakage. All 1,600+ test suite assertions across the system are green.

Run configuration command used to validate the project modules:

sbt clean compile test

Was this PR authored or co-authored using generative AI tooling?

Yes. Generative AI (Gemini) was utilized as an external assistant to analyze complex multi-threaded JDBC/jOOQ connection trace errors and help structure the safe connection lifecycle fallback logic in SqlServer.scala. No direct IDE-integrated automation tools were used to auto-generate codebase files.

Yicong-Huang and others added 9 commits July 2, 2026 11:16
Each spec that mixes in MockTexeraDB used to start its own
EmbeddedPostgres in beforeAll. Once the global Tags.limit(Tags.Test, 1)
restriction was lifted, these specs ran in parallel and collided on
the shared /tmp/embedded-pg/<binary>/ directory with an
OverlappingFileLockException at EmbeddedPostgres.prepareBinaries.

Move the EmbeddedPostgres + DSLContext fields onto a companion object,
make ensureInitialized() idempotent and synchronized, and turn
shutdownDB() into a no-op so the singleton lives for the JVM. The
trait still exposes the same methods so spec callers do not change.
@github-actions github-actions Bot added engine common platform Non-amber Scala service paths labels Jul 7, 2026
@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Automated Reviewer Suggestions

Based on the git blame history of the changed files, we recommend the following reviewers:

  • Contributors with relevant context: @Yicong-Huang, @carloea2
    You can notify them by mentioning @Yicong-Huang, @carloea2 in a comment.

@Neilk1021 Neilk1021 changed the title Task/singleton mock texera db refactor: Refactor MockTexeraDB into a JVM singleton Jul 7, 2026
@codecov-commenter

codecov-commenter commented Jul 7, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 59.77%. Comparing base (24b587f) to head (642ea2b).
⚠️ Report is 108 commits behind head on main.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@             Coverage Diff              @@
##               main    #6238      +/-   ##
============================================
+ Coverage     56.89%   59.77%   +2.88%     
- Complexity     3058     3370     +312     
============================================
  Files          1129     1128       -1     
  Lines         43802    43856      +54     
  Branches       4743     4753      +10     
============================================
+ Hits          24922    26217    +1295     
+ Misses        17449    16207    -1242     
- Partials       1431     1432       +1     
Flag Coverage Δ *Carryforward flag
access-control-service 70.00% <ø> (ø)
agent-service 44.59% <ø> (ø) Carriedforward from ecdcb92
amber 66.13% <ø> (+7.48%) ⬆️
computing-unit-managing-service 0.00% <ø> (ø)
config-service 52.30% <ø> (ø)
file-service 63.97% <ø> (+1.16%) ⬆️
frontend 50.12% <ø> (ø) Carriedforward from ecdcb92
notebook-migration-service 78.57% <ø> (ø)
pyamber 91.15% <ø> (ø) Carriedforward from ecdcb92
python 90.69% <ø> (ø) Carriedforward from ecdcb92
workflow-compiling-service 55.14% <ø> (ø)

*This pull request uses carry forward flags. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

⚠️ Benchmark changes need a look

🟢 2 better · 🔴 6 worse · ⚪ 7 noise (<±5%) · 0 without baseline

Compared against main 7c135ee benchmarked on this same runner, so the delta is largely free of cross-runner hardware noise. The "7d avg" column still reflects the gh-pages dashboard. Treat <±5% as noise unless repeated.

Dashboard · Run

config throughput MB/s latency max Δ latest / 7d
🔴 bs=10 sw=10 sl=64 394 0.24 24,622/37,341/37,341 us 🔴 +19.4% / 🔴 +138.6%
🔴 bs=100 sw=10 sl=64 798 0.487 124,993/135,105/135,105 us 🟢 -12.4% / 🔴 +23.8%
bs=1000 sw=10 sl=64 897 0.548 1,105,152/1,219,585/1,219,585 us ⚪ within ±5% / 🔴 +16.6%
Baseline details

Latest main 7c135ee from same runner

config metric PR latest main 7d avg Δ latest Δ 7d
bs=10 sw=10 sl=64 throughput 394 tuples/sec 416 tuples/sec 760.25 tuples/sec -5.3% -48.2%
bs=10 sw=10 sl=64 MB/s 0.24 MB/s 0.254 MB/s 0.464 MB/s -5.5% -48.3%
bs=10 sw=10 sl=64 p50 24,622 us 23,267 us 12,873 us +5.8% +91.3%
bs=10 sw=10 sl=64 p95 37,341 us 31,271 us 15,648 us +19.4% +138.6%
bs=10 sw=10 sl=64 p99 37,341 us 31,271 us 19,338 us +19.4% +93.1%
bs=100 sw=10 sl=64 throughput 798 tuples/sec 828 tuples/sec 974.75 tuples/sec -3.6% -18.1%
bs=100 sw=10 sl=64 MB/s 0.487 MB/s 0.506 MB/s 0.595 MB/s -3.8% -18.1%
bs=100 sw=10 sl=64 p50 124,993 us 118,980 us 102,470 us +5.1% +22.0%
bs=100 sw=10 sl=64 p95 135,105 us 154,259 us 109,144 us -12.4% +23.8%
bs=100 sw=10 sl=64 p99 135,105 us 154,259 us 115,530 us -12.4% +16.9%
bs=1000 sw=10 sl=64 throughput 897 tuples/sec 910 tuples/sec 1,000 tuples/sec -1.4% -10.3%
bs=1000 sw=10 sl=64 MB/s 0.548 MB/s 0.555 MB/s 0.61 MB/s -1.3% -10.2%
bs=1000 sw=10 sl=64 p50 1,105,152 us 1,097,711 us 1,005,545 us +0.7% +9.9%
bs=1000 sw=10 sl=64 p95 1,219,585 us 1,205,873 us 1,045,968 us +1.1% +16.6%
bs=1000 sw=10 sl=64 p99 1,219,585 us 1,205,873 us 1,076,800 us +1.1% +13.3%
Raw CSV
config_idx,batch_size,schema_width,string_len,num_batches,total_ms,total_tuples,total_bytes,tuples_per_sec,mb_per_sec,lat_p50_us,lat_p95_us,lat_p99_us
0,10,10,64,20,507.89,200,128000,394,0.240,24622.31,37341.21,37341.21
1,100,10,64,20,2506.78,2000,1280000,798,0.487,124993.34,135104.50,135104.50
2,1000,10,64,20,22289.98,20000,12800000,897,0.548,1105151.89,1219585.40,1219585.40

@Neilk1021

Copy link
Copy Markdown
Contributor Author

I noticed that the withTransaction block in DatasetResource.scala has gotten a bit bloated/heavy, which is likely contributing to the latency spikes seen in the benchmarks. I'm planning to submit a follow-up fix to slim down the transaction scope, but wanted to call it out here.

@aglinxinyuan

Copy link
Copy Markdown
Contributor

I noticed that the withTransaction block in DatasetResource.scala has gotten a bit bloated/heavy, which is likely contributing to the latency spikes seen in the benchmarks. I'm planning to submit a follow-up fix to slim down the transaction scope, but wanted to call it out here.

You can open an issue for this.

@aglinxinyuan

Copy link
Copy Markdown
Contributor

@Yicong-Huang, can you take a look at Benchmark? Is it supposed to be better?

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Refactors the test database infrastructure to use a JVM-wide singleton EmbeddedPostgres, provisioning per-suite isolated databases to reduce test runtime and avoid concurrent extraction/file-lock issues, while also adjusting transaction handling in SqlServer.withTransaction to better tolerate mixed autoCommit states seen in concurrent tests.

Changes:

  • Converted MockTexeraDB into a singleton-backed design with cached DDL loading and per-suite database creation.
  • Updated multipart-upload concurrency tests to use independent JDBC connections against the per-suite database.
  • Reworked SqlServer.withTransaction to manually manage autoCommit / commit / rollback behavior.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.

File Description
file-service/src/test/scala/org/apache/texera/service/resource/DatasetResourceSpec.scala Switches lock-simulation tests to use independent JDBC connections from the singleton embedded Postgres.
common/dao/src/test/scala/org/apache/texera/dao/MockTexeraDB.scala Introduces JVM-singleton EmbeddedPostgres, caches cleaned DDL, creates per-suite databases, and manages per-test cleanup.
common/dao/src/main/scala/org/apache/texera/dao/SqlServer.scala Replaces jOOQ-managed transactions with manual connection/autoCommit handling in withTransaction.
amber/src/test/scala/org/apache/texera/amber/engine/e2e/TestUtils.scala Updates e2e DB initialization to use the singleton embedded Postgres + cached DDL.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread common/dao/src/test/scala/org/apache/texera/dao/MockTexeraDB.scala Outdated
Comment on lines +137 to +157
} finally {
try {
if (!conn.isClosed) {
scala.util.Using.resource(conn.createStatement()) { stmt =>
stmt.execute(
"""
DO $$ DECLARE
r RECORD;
BEGIN
FOR r IN (SELECT tablename FROM pg_tables WHERE schemaname = 'public') LOOP
EXECUTE 'TRUNCATE TABLE ' || quote_ident(r.tablename) || ' CASCADE';
END LOOP;
END $$;
"""
)
}
}
} catch {
case e: Exception => e.printStackTrace()
}
}
def getDDLScript: String = ddlScript.getOrElse(throw new RuntimeException("DDL not loaded"))
}

trait MockTexeraDB extends AnyFlatSpecLike {
Comment on lines +106 to +128
val txCtx = org.jooq.impl.DSL.using(conn, dsl.dialect())
val result = block(txCtx)

if (originalAutoCommit) {
conn.commit()
}

result
} catch {
case e: Throwable =>
if (originalAutoCommit) {
conn.rollback()
}
throw e
} finally {
try {
if (originalAutoCommit != conn.getAutoCommit) {
conn.setAutoCommit(originalAutoCommit)
}
} finally {
provider.release(conn)
}
}
@Yicong-Huang

Copy link
Copy Markdown
Contributor

@Yicong-Huang, can you take a look at Benchmark? Is it supposed to be better?

please ignore benchmark. it is quite not stable. until we stabilize it, the signals are informational only.

@chenlica chenlica requested review from mengw15 and removed request for Xiao-zhen-Liu July 8, 2026 06:11
@chenlica

chenlica commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

@mengw15 Please review it as well.

Neilk1021 and others added 3 commits July 8, 2026 11:05
Adds proper guards to MockTexeraDB initialization to guard against the DDL script not being loaded.

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Neil Ketteringham <53205839+Neilk1021@users.noreply.github.com>
…exeraDB's single connection with Hikari Connection pooling
@Yicong-Huang

Copy link
Copy Markdown
Contributor

Thanks @Neilk1021 for the PR, please wait for my review, might need 1 day or 2 to find time. meanwhile, I hope to loop in @mengw15 as he is modifying CI as well for another effort. @mengw15 please post your related issues here to also give @Neilk1021 some context.

@mengw15

mengw15 commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Hi @Neilk1021 👋 — for context, here's the CI work I have in flight (in .github/workflows/build.yml):

Looks like we're on different layers — you're optimizing the embedded unit-test DB (MockTexeraDB), I'm adding CI jobs that provision real postgres/MinIO and boot the packaged services — so no file overlap. Flagging for awareness; happy to sync if the platform integration-test DB path ends up mattering.

@Neilk1021

Neilk1021 commented Jul 8, 2026

Copy link
Copy Markdown
Contributor Author

For future reviewers, small notes on why I reverted my changes to with transaction and implemented Hikari pooling for MockTexeraDB.

First, my earlier withTransaction changes modified production business logic and added weight purely to work around a test bug. That was a stop-gap fueled by my own misdiagnosis of where the bug was actually coming from, so I've reverted withTransaction back to the jOOQ-native form.

The real root cause: backing MockTexeraDB with a single physical connection creates a failure mode that doesn't exist in production. Under concurrency, multiple threads share one connection and race on its autocommit state, producing flaky Cannot commit transaction failures. Production uses a pooled DataSource where each thread gets its own connection, so it never sees this. Fixing it at the harness layer makes the test topology match production and lets withTransaction stay as the clean one-liner.

On test speed: the physical connection was never the bottleneck. The expensive part was spinning up EmbeddedPostgres instances, so this PR boots one shared instance per JVM and gives each suite its own isolated database via a cheap CREATE DATABASE. Pooling adds negligible per-op overhead on top of that.
On the benchmark deltas: they're within the harness's known noise (single-run, and the flagged reds are p95/p99 off ~20 samples, which is dominated by tail variance). There's also no code path from a test-only change to the Arrow Flight data plane, so I don't believe these reflect a real regression. However, I'm happy to re-run if useful.

@Neilk1021

Neilk1021 commented Jul 8, 2026

Copy link
Copy Markdown
Contributor Author

Looks like we're on different layers — you're optimizing the embedded unit-test DB (MockTexeraDB), I'm adding CI jobs that provision real postgres/MinIO and boot the packaged services — so no file overlap. Flagging for awareness; happy to sync if the platform integration-test DB path ends up mattering.

Thanks for the context!

@chenlica

chenlica commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

@mengw15 @Neilk1021 : as you two work very "closely," feel free to have offline discussions and report the results on this PR.

@Xiao-zhen-Liu Xiao-zhen-Liu left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for taking this on — the core design is a clear improvement: one embedded Postgres per JVM, a fresh database per suite, cached DDL, and a real pool are the right shape, and the startup-time win is real. I ran the changed e2e specs on JDK 11 to confirm the embedded-DB switch is safe (note on TestUtils below), and it holds up.

One thing I think should block merge: the per-test cleanup in withFixture doesn't actually run. It truncates the public schema, but all our tables are in the texera_db schema (sql/texera_ddl.sql:42-43), so it matches zero tables. I confirmed by running ComputingUnitAccessSpec and FileResolverSpec on this branch — both pass, but only because the beforeAll seed is never deleted; when I pointed the truncation at the real schema, ComputingUnitAccessSpec failed 3/5. So "each test starts clean" isn't true today, and it can't be fixed by just changing the schema name without also moving several suites' beforeAll seeding into beforeEach. I'd suggest either dropping the per-test truncation and keeping each suite's own cleanup, or making it real and fixing the affected suites here.

Two notes so the description stays accurate: it mentions a SqlServer.withTransaction change, but SqlServer.scala isn't in the diff — the autoCommit fix actually comes from the new pool plus the DatasetResourceSpec connection change. And this is good groundwork toward parallel suites (#4525) but doesn't get us there yet: production code still reads through the single global SqlServer, which only works while Tags.limit keeps tests sequential. Worth saying that explicitly, and that the e2e embedded-DB switch depends on #4179 having landed. Smaller cleanups are inline.

What's still TODO for the series: (1) decide + fix the per-test cleanup; (2) make the SqlServer context per-suite/thread (the real prerequisite for parallel suites); (3) only then remove Tags.limit + enable parallelExecution; (4) drop created DBs, remove the now-dead jdbcUrlForTestCases config, dedupe the provisioning helper, avoid the double pool.

DO $$ DECLARE
r RECORD;
BEGIN
FOR r IN (SELECT tablename FROM pg_tables WHERE schemaname = 'public') LOOP

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This per-test cleanup is a silent no-op (targets the wrong schema). It truncates the public schema, but every table lives in texera_db (sql/texera_ddl.sql:42-43 creates that schema and sets search_path), so pg_tables WHERE schemaname='public' matches nothing. Verified on JDK 11: ComputingUnitAccessSpec and FileResolverSpec pass only because the beforeAll seed is never deleted; retargeting the truncation at texera_db makes ComputingUnitAccessSpec fail 3/5. Two consequences: (1) "each test starts clean" is false today — the trait adds no per-test isolation, which is a trap for anyone who later drops a suite's own cleanup trusting this; (2) you can't just fix the schema name, because that breaks every suite that seeds only in beforeAll (AccessControlResourceSpec, ComputingUnitAccessSpec, WorkflowResourceSpec, FileResolverSpec, and the DatasetResourceSpec this PR touches). Suggest either dropping the truncation and keeping each suite's existing cleanup, or making it real and moving those seeds to beforeEach.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think removing the truncation for now and leaving the truncation logic for later would be best? This allows us to get the speed-up now without ballooning the responsibilities of this PR?

}
}
} catch {
case e: Exception => e.printStackTrace()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the truncation throws it's only printed and swallowed, so the next test can start against dirty state. If the cleanup stays, a failure to clean should fail loudly rather than print-and-continue.

testScopedContext = Some(scopedCtx)

// Point the Texera backend exactly to this suite's isolated database
SqlServer.initConnection(jdbcUrl, "postgres", "")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SqlServer.initConnection constructs a SqlServer whose constructor eagerly opens its own 10-connection Hikari pool (SqlServer.scala:62, minimumIdle=2), and the next line swaps in the trait's separate pool. So each trait suite opens two pools and the SqlServer-owned one is never used. Consider a SqlServer method that repoints its existing pool, or reuse that pool instead of building a new DataSourceConnectionProvider.


sqlServerInstance.replaceDSLContext(dslContext.get)
try {
sqlServerInstance.replaceDSLContext(activeContext)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Per-suite isolation is real for getDSLContext, but production DAOs read through the single global SqlServer, which this repoints per test. That's safe only while Tags.limit(Tags.Test,1) keeps suites sequential (still in all 12 build.sbt). Once #4525 removes that, two suites in one JVM race on this global — and initConnection closing the prior instance's pool can drop a pool another suite is using. Worth noting this PR is groundwork; parallel-safety needs a follow-up that makes the context per-suite/thread.

def initializeDBAndReplaceDSLContext(): Unit = {
assert(dbInstance.isEmpty && dslContext.isEmpty)
val parts: Array[String] = content.split("(?m)^CREATE DATABASE :\"DB_NAME\";")
val sqlBody = if (parts.length > 1) parts(1) else content

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the CREATE DATABASE split marker ever changes, parts.length > 1 is false and this silently runs the whole DDL as the body. A hard failure would be safer than quietly doing the wrong thing.

sql.linesIterator.filterNot(_.trim.startsWith("\\c")).mkString("\n")

val embedded = EmbeddedPostgres.builder().start()
var tablesAndIndexCreation = removeCCommands(sqlBody)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tablesAndIndexCreation is never reassigned — can be a val.

import scala.util.Using

/**
* Provides a JVM-singleton EmbeddedPostgres for tests. Multiple specs that mix

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This credits the singleton with avoiding OverlappingFileLockException "in parallel," but tests still run sequentially (Tags.limit is in place), so the actual current win is booting Postgres once. Worth aligning the comment with today's behavior.

testScopedContext.get
}

def getDBInstance: EmbeddedPostgres = MockTexeraDB.getDBInstance

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor readability: getDBInstance exists on both the object and this trait, and there are two init entry points (ensureInitialized vs initializeDBAndReplaceDSLContext). A line of doc on each boundary would save a maintainer some head-scratching.

}
}

val targetDbConn = embedded.getDatabase("postgres", dbName).getConnection

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few things in this method: (1) it duplicates the "create DB + run DDL" sequence from the trait (MockTexeraDB.scala:101-114) and the copies have already drifted — worth one shared helper on object MockTexeraDB. (2) targetDbConn is closed manually after the Using.resource, so it leaks if execute throws — wrap it in Using.resource too. (3) The DROP DATABASE IF EXISTS on a freshly generated UUID name (line 208) is dead. (4) This quietly moves the e2e specs off the external test Postgres onto the embedded one — a real (good) change worth a line in the description; it depends on #4179. I ran the e2e specs this way on JDK 11 (46 tests ×3, no Connection refused), so the switch looks safe for sequential runs.


val connectionProvider = getDSLContext.configuration().connectionProvider()
val connection = connectionProvider.acquire()
val connection = MockTexeraDB.getDBInstance.getDatabase("postgres", uniqueDbName).getConnection

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Opening a raw connection via MockTexeraDB.getDBInstance.getDatabase(...) works (jOOQ qualifies the schema), but it couples the test to the trait's internals — a small newRawConnection() helper on the trait would read cleaner, and the same pattern repeats at 5 other sites in this file. Minor: getConnection + setAutoCommit(false) run before the try, so an early throw would leak the connection.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

common engine platform Non-amber Scala service paths

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Extract JVM-singleton MockTexeraDB infrastructure for parallel testing

8 participants